package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strconv"
	"strings"
	"sync"
)

// BlogPost 定义了博客文章的结构
type BlogPost struct {
	ID      int    `json:"id"`
	Title   string `json:"title"`
	Content string `json:"content"`
	Author  string `json:"author"`
}

// blogPosts 存储了所有博客文章
var blogPosts []BlogPost
var mutex sync.Mutex
var idCounter int

func main() {
	http.HandleFunc("/posts", postsHandler)
	http.HandleFunc("/posts/", postHandler)

	// 监听并在8080端口启动服务器
	fmt.Println("Server is listening on port 8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		fmt.Println("Error starting server:", err)
	}
}

func postsHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case http.MethodGet:
		mutex.Lock()
		postsJSON, _ := json.Marshal(blogPosts)
		mutex.Unlock()
		w.Header().Set("Content-Type", "application/json")
		w.Write(postsJSON)
	case http.MethodPost:
		var newPost BlogPost
		bodyBytes, err := ioutil.ReadAll(r.Body)
		if err != nil {
			http.Error(w, "Invalid request", http.StatusBadRequest)
			return
		}
		err = json.Unmarshal(bodyBytes, &newPost)
		if err != nil {
			http.Error(w, "Invalid JSON", http.StatusBadRequest)
			return
		}
		mutex.Lock()
		idCounter++
		newPost.ID = idCounter
		blogPosts = append(blogPosts, newPost)
		mutex.Unlock()
		w.WriteHeader(http.StatusCreated)
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}

func postHandler(w http.ResponseWriter, r *http.Request) {
	idStr := strings.TrimPrefix(r.URL.Path, "/posts/")
	id, err := strconv.Atoi(idStr)
	if err != nil {
		http.Error(w, "Invalid post ID", http.StatusBadRequest)
		return
	}

	switch r.Method {
	case http.MethodGet:
		found := false
		for _, post := range blogPosts {
			if post.ID == id {
				postJSON, _ := json.Marshal(post)
				w.Header().Set("Content-Type", "application/json")
				w.Write(postJSON)
				found = true
				break
			}
		}
		if !found {
			http.NotFound(w, r)
		}
	case http.MethodDelete:
		found := false
		for i, post := range blogPosts {
			if post.ID == id {
				mutex.Lock()
				blogPosts = append(blogPosts[:i], blogPosts[i+1:]...)
				mutex.Unlock()
				w.WriteHeader(http.StatusOK)
				found = true
				break
			}
		}
		if !found {
			http.NotFound(w, r)
		}
	default:
		w.WriteHeader(http.StatusMethodNotAllowed)
	}
}
